home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / do_menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-17  |  8.2 KB  |  300 lines

  1. /*                        Copyright (c) 1987 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: do_menu.c,v 1.1 89/03/17 08:21:04 sau Exp $
  9.     $Source: /m1/mgr.new/src/RCS/do_menu.c,v $
  10. */
  11. static char    RCSid_[] = "$Source: /m1/mgr.new/src/RCS/do_menu.c,v $$Revision: 1.1 $";
  12. /* high level menu manipulation routines */
  13.  
  14. #include "bitmap.h"
  15. #include <stdio.h>     /* temporary */
  16. #include "menu.h"
  17. #include "defs.h"
  18. #include "font.h"
  19.  
  20. /* do a tree of menus */
  21.  
  22. static int x_page = 5;        /* offset for paging menu */
  23. static int y_page = -5;
  24. static int x_slide = 40;    /* offset for scrolling menu */
  25. static int y_slide = 10;
  26.  
  27. struct menu_result *
  28. do_menus(screen,mouse,x,y,font,menu_list,menu,exit_code)
  29. BITMAP *screen;            /* bitmap screen */
  30. int mouse;            /* fd to get mouse coordinates */
  31. int x,y;            /* where the menu goes on the screen */
  32. struct font *font;        /* font to use for menus */
  33. struct menu_state *menu_list[];    /* list of available menus */
  34. int menu;            /* current menu number */
  35. int exit_code;            /* valid exit codes */
  36.    {
  37.    struct menu_state  *state;    /* 'cookie' for menu system */
  38.    struct menu_result *result;    /* messages for nodes of menu tree chosen */
  39.    int done=0;            /* true if ok to backup a level */
  40.    int first = 1;        /* true upon entry */
  41.    int next;            /* next menu # */
  42.    struct menu_result *add_result();
  43.    char *print_menu();
  44.  
  45.    /* set up menu, get menu 'cookie' */
  46.  
  47.    state = menu_list[menu];    /* fetch the menu state */
  48.    result = (struct menu_result *) 0;
  49.    state = menu_setup(state,screen,x,y,menu_choice(state));
  50.  
  51.    if (state == (struct menu_state *) 0) {
  52.        perror("Error setting up menu");
  53.        return(NULL);
  54.        }
  55.  
  56.    /* see if another page */
  57.  
  58.    if (state->next >= 0)
  59.       exit_code |= EXIT_BOTTOM;
  60.    else
  61.       exit_code &= ~EXIT_BOTTOM;
  62.  
  63. #ifdef DEBUG
  64.    dprintf(m)(stderr,"  Setting up menu %d at %d,%d: valid states %s\n",
  65.                       menu,x,y,print_menu(exit_code));
  66. #endif
  67.  
  68.    /* get selection on current menu */
  69.  
  70.    while (!done)
  71.      {
  72.  
  73.      /* get menu state from user */
  74. #ifdef DEBUG
  75.    dprintf(m)(stderr,"  from user ..."); fflush(stderr);
  76. #endif
  77.  
  78.      /* do auto right menus */
  79.  
  80.      if (state->flags&MENU_PAGE && exit_code&EXIT_BOTTOM && first &&
  81.                      state->current >= state->count ) {
  82.         first=0;
  83.         state->exit = EXIT_BOTTOM;
  84.         }
  85.      else if (state->flags&MENU_AUTO && exit_code&EXIT_RIGHT && first) {
  86.         first=0;
  87.         state->exit = EXIT_RIGHT;
  88.         }
  89.      else
  90.         menu_get(state,mouse,0,exit_code);
  91.  
  92.      /* execute appropriate state action */
  93.  
  94. #ifdef DEBUG
  95.    dprintf(m)(stderr,"got menu %d (at %d,%d) selection %d (%s)\n",
  96.               menu,x,y,menu_choice(state),print_menu(menu_exit(state)));
  97. #endif
  98.  
  99.      switch (menu_exit(state)) {
  100.         case EXIT_LEFT:        /* slid off to the left */
  101.         case EXIT_TOP:        /* slid of the top */
  102.              result = NULL;
  103.              done++;
  104.              break;
  105.         case EXIT_CHOICE:    /* add current choice onto list */
  106.              result = add_result(state,result);
  107.              done++;
  108.              break;
  109.         case EXIT_RIGHT:    /* slid off top the right */
  110.              if ((next = menu_next(state)) >=0 &&    /* link exists */
  111.                      menu_list[next] &&            /* menu exists */
  112.                      menu_list[next]->save == (BITMAP *) 0 &&    /* not used */
  113.                      (result=do_menus(screen,mouse,        /* choice */
  114.                                       x+x_slide,y-y_slide,font,menu_list,
  115.                                       next,exit_code|EXIT_LEFT))) {
  116.                 done++;
  117.                 }
  118.              break;
  119.         case EXIT_BOTTOM:
  120.              if ((next = menu_next(state)) >=0 &&    /* menu exists */
  121.                  menu_list[next]->save == (BITMAP *) 0 &&    /* not used */
  122.                      (result=do_menus(screen,mouse,        /* choice */
  123.                                       x+x_page,y+y_page,font,menu_list,
  124.                                       next,exit_code|EXIT_TOP))) {
  125.                 done++;
  126.                 }
  127.              break;
  128.         default:
  129.          if( !debug )
  130.         break;
  131.              fprintf(stderr,"invalid menu state: 0%o\n",menu_exit(state));
  132.              result = NULL;
  133.              done++;
  134.              break;
  135.         }
  136.      }
  137.   
  138. #ifdef DEBUG
  139.    dprintf(m)(stderr,"  Tearing down %d at %d,%d choice: %d, returning: %s\n",
  140.               menu,x,y,menu_choice(state),print_menu(menu_exit(state)));
  141. #endif
  142.  
  143.    /* add our action onto action list */
  144.  
  145.    if (menu_exit(state) == EXIT_RIGHT && result && !(state->flags&MENU_SNIP)) {
  146.       result = add_result(state,result);
  147.       }
  148.  
  149.    /* erase menu from the screen */
  150.  
  151.    menu_remove(state);
  152.    return(result);
  153.    }
  154.  
  155. /* add a value to list of menu values */
  156.  
  157. struct menu_result *
  158. add_result(state,list)
  159. struct menu_state *state;        /* menu to add choice to */
  160. struct menu_result *list;        /* current list of results */
  161.    {
  162.    register struct menu_result *current;    /* current result */
  163.    char *malloc();
  164.  
  165.    /* set up list */
  166.  
  167.    if (list == (struct menu_result *) 0) {
  168.       list = (struct menu_result *) malloc(sizeof(struct menu_result));
  169.       list->next = NULL;
  170.       list->value = NULL;
  171.       }
  172.    else if (list->value == NULL)
  173.       return(list);
  174.  
  175.    /* add entry to existing list */
  176.  
  177.    if (menu_value(state) && *menu_value(state) && 
  178.                       (current = (struct menu_result *) 
  179.                        malloc(sizeof(struct menu_result)))) {
  180.       current->value = menu_value(state);
  181.       current->next = list;
  182.       }
  183.    else
  184.       current = list;
  185.    return(current);
  186.    }
  187.  
  188. /* do a tree of menus */
  189.  
  190. go_menu(n)
  191. int n;                    /* which menu button (0 or 1) */
  192.    {
  193.    struct menu_result *result = NULL;        /* result of menu selection */
  194.    register struct menu_result *current;    /* current action */
  195.    int pushed;
  196.    int exit = EXIT_RIGHT;            /* enable sliding and paging */
  197.    register int menu = ACTIVE(menu[n]);
  198.  
  199. #ifdef DEBUG
  200.    dprintf(m)(stderr,"Starting menu %d, button %d\n",menu,n);
  201. #endif
  202.  
  203.    /* go get a menu selection, return list of actions */
  204.  
  205.    if (menu>=0 /* && mousein(mousex,mousey,active,0) */) {
  206.       result = do_menus(screen,mouse,mousex,mousey,
  207.                font,ACTIVE(menus),menu,exit);
  208.  
  209.       /* send list of actions, and free action space */
  210.  
  211.       for(current=result;current;) {
  212.          if (current->value)
  213.             Write(ACTIVE(to_fd),current->value,strlen(current->value));
  214.          result = current;
  215.          current = current->next;
  216.          free(result);
  217.          }
  218.         
  219.       /* button is no longer pushed down; record that fact */
  220.       do_button( 0 );
  221.       }
  222.    return;
  223.    }
  224.  
  225. /* define a menu from menu download string */
  226.  
  227. struct menu_state *
  228. do_menu(line,font,fg,bg)
  229. char *line;
  230. struct font *font;
  231. int fg,bg;        /* fg and bg color */
  232.    {
  233.    register int count;
  234.    char *fields[MAXITEMS];
  235.  
  236.    count = get_fields(line+1,*line,fields,MAXITEMS)/2;
  237.  
  238. #ifdef DEBUG
  239.    dprintf(m)(stderr,"Setting up a menu, %d items\n",count);
  240. #endif
  241.    if (count < 1)
  242.       return((struct menu_state *) 0);
  243.  
  244.    return(menu_define(font,fields,fields+count,count,fg,bg));
  245.    }
  246.  
  247.  
  248. /*******************************************************************************
  249.  *
  250.  * break a line into its component fields 
  251.  */
  252.  
  253. static int
  254. get_fields(line,delim,fields,max)
  255. char *line;                /* line to break into fields */
  256. char **fields;                /* resultant fields */
  257. char delim;                /* field delimeter */
  258. int max;                /* max # fields */
  259.    {
  260.    register char c, *start;
  261.    register int count;
  262.  
  263.    for(count=0,start=line; count<max && (c = *line); line++)
  264.       if (c == delim) {
  265.          fields[count++]=start;
  266.          *line = '\0';
  267.          start=line+1;
  268.          }
  269.    if (start<line)
  270.        fields[count++] = start;
  271.    fields[count]=(char *) 0;
  272.    return(count);
  273.    }
  274.  
  275. /* set slideing defaults */
  276.  
  277. int
  278. set_slide(x,y)
  279. int x,y;
  280.    {
  281.    if (x || y) {
  282.       x_slide = x;
  283.       y_slide = y;
  284.       }
  285.    return(0);
  286.    }
  287.  
  288. /* set paging defaults */
  289.  
  290. int
  291. set_page(x,y)
  292. int x,y;
  293.    {
  294.    if (x || y) {
  295.       x_page = x;
  296.       y_page = y;
  297.       }
  298.    return(0);
  299.    }
  300.